/*
 * Copyright (c) Soon.Liao 2024. All rights reserved.
 * @Author: soon.liao
 * @Date: 2024-11-23 22:18:30
 * @LastEditors: soon.liao
 * @LastEditTime: 2024-11-28 23:33:19
 * @FilePath: /near_link_sdk/applications/sample/wifi-iot/app/rgb_controller/radar/radar_control.c
 * @Description: Create Date : 2024
 * NA
 */
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "soc_osal.h"
#include "radar_service.h"
#include "radar_control.h"
#include "cmd_json.h"
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_CLIENT)
#include "sence.h"
#endif

#define RADAR_START_DELAY 1000

#define RADAR_STATUS_CALI_ISO 4
#define RADAR_STATUS_QUERY_DELAY 10000

#define RADAR_DEFAULT_LOOP 8
#define RADAR_DEFAULT_PERIOD 5000
#define RADAR_DEFAULT_DBG_TYPE 1
#define RADAR_DEFAULT_WAVE 2

#define RADAR_API_NO_HUMAN 0
#define RADAR_API_RANGE_CLOSE 50
#define RADAR_API_RANGE_NEAR 100
#define RADAR_API_RANGE_MEDIUM 200
#define RADAR_API_RANGE_FAR 600

#define CONFIG_RED_LED_PIN 7
#define CONFIG_GREEN_LED_PIN 11
#define CONFIG_YELLOW_LED_PIN 10

#define RADAR_TASK_PRIO 24
#define RADAR_TASK_STACK_SIZE 0x1000

typedef struct {
    uint8_t times; // 发射次数, 0-无限次
    uint8_t loop;  // 单次雷达工作, TRx的波形数量
    uint8_t ant;   // Rx天线数量
    uint8_t wave;  // 波形选择, 0-320M/40M CTA, 1-160M/20M CW
    uint8_t dbg_type; // 维测方式. 0-不外发维测数据, 1-外发脉压后的数据, 2-外发相干累加后的数据
    uint16_t period; // 雷达工作间隔
} radar_driver_para_t;

static void radar_set_driver_para_weakref(radar_driver_para_t *para) __attribute__((weakref("radar_set_driver_para")));

static uint8_t led_on_by_user_flag = 0;
static uint8_t enable_radar_on_off = 0;

static void radar_ctrl_set(radar_result_t *res)
{
    if (enable_radar_on_off == 0) {
        osal_printk("[RADAR_CONTROL] enable_radar_on_off disable\r\n");
        return;
    }
    if (res->is_human_presence == 1) {
        if (res->lower_boundary == 0 && res->upper_boundary == RADAR_API_RANGE_NEAR) {
            osal_printk("[RADAR_CONTROL] R 0-1 meters\r\n");
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_SERVER)
            create_json_wifi_cammand(CMD_ON);
#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_CLIENT)
            rgb_led_strip_set_on();
#endif
        } else if ((res->lower_boundary == RADAR_API_RANGE_NEAR && res->upper_boundary == RADAR_API_RANGE_MEDIUM)) {
            osal_printk("[RADAR_CONTROL] R 1-2 meters\r\n");
        } else {
            osal_printk("[RADAR_CONTROL] R 2-6 meters\r\n");
        }
    } else {
        osal_printk("[RADAR_CONTROL] is_human_presence = 0\r\n");
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_SERVER)
        create_json_wifi_cammand(CMD_OFF);
#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_CLIENT)
        rgb_led_strip_set_off();
#endif
    }
}

static void radar_result_cb(radar_result_t *res)
{
    osal_printk("[RADAR_CONTROL] lb:%u, hb:%u, hm:%u\r\n", res->lower_boundary, res->upper_boundary,
                res->is_human_presence);
    osal_printk("[RADAR_CONTROL] %s\r\n", res->is_human_presence == 1 ? "Human presence" : "No human presence");
    radar_ctrl_set(res);
}

void radar_sta_para_init(void)
{
    osal_printk("[RADAR_CONTROL] radar_sta_para_init!\r\n");

    radar_dbg_para_t dbg_para;
    dbg_para.times = 0;
    dbg_para.loop = RADAR_DEFAULT_LOOP;
    dbg_para.ant = 0;
    dbg_para.wave = RADAR_DEFAULT_WAVE;
    dbg_para.dbg_type = RADAR_DEFAULT_DBG_TYPE;
    dbg_para.period = RADAR_DEFAULT_PERIOD;
    uapi_radar_set_debug_para(&dbg_para);

    radar_sel_para_t sel_para;
    sel_para.height = 0;
    sel_para.scenario = 0;
    sel_para.material = 2;
    sel_para.fusion_track = 1;
    sel_para.fusion_ai = 1;
    uapi_radar_select_alg_para(&sel_para);

    radar_alg_para_t alg_para;
    alg_para.d_th_1m = 32;
    alg_para.d_th_2m = 27;
    alg_para.p_th = 30;
    alg_para.t_th_1m = 13;
    alg_para.t_th_2m = 26;
    alg_para.b_th_ratio = 50;
    alg_para.b_th_cnt = 15;
    alg_para.a_th = 70;
    uapi_radar_set_alg_para(&alg_para, 0);
}

void radar_softap_para_init(void)
{
    osal_printk("[RADAR_CONTROL] radar_softap_para_init!\r\n");

    radar_driver_para_t para;
    para.ant = 0;
    para.dbg_type = RADAR_DEFAULT_DBG_TYPE;
    para.loop = RADAR_DEFAULT_LOOP;
    para.period = RADAR_DEFAULT_PERIOD;
    para.times = 0; // 1-使用软件控雷达, 0-使用硬件控雷达
    para.wave = RADAR_DEFAULT_WAVE;
    radar_set_driver_para_weakref(&para);
}
void radar_get_status_from_kv(void)
{
    uint16_t kvalue_length;
    uint8_t kvalue;
    uint32_t errcode;
    errcode = key_value_rgb_master_radar_on_off_read(&kvalue, &kvalue_length);
    osal_printk("\r\n key_value_rgb_master_radar_on_off_read kvalue =%d kvalue_length=%d\r\n", kvalue, kvalue_length);
    if (errcode != 0) {
        osal_printk("\r\n key_value_rgb_master_radar_on_off_read no success\r\n");
    } else {
        enable_radar_on_off = kvalue;
        osal_printk("\r\n key_value_rgb_master_radar_on_off_read enable_radar_on_off =%d\r\n", enable_radar_on_off);
    }
}

void radar_check_status_task(void)
{
    osal_printk("[RADAR_CONTROL] radar_check_status_task!\r\n");
    uapi_radar_register_result_cb(radar_result_cb);
    // 遍历1~13信道隔离度, 选取最佳隔离度进行雷达探测
    osal_msleep(RADAR_START_DELAY);
    // uapi_radar_set_status(RADAR_STATUS_START);
    uapi_radar_set_status(RADAR_STATUS_CALI_ISO);
    while (1) {
        uapi_radar_set_delay_time(8); // 设置退出延迟时间为8S,目前最小时间为8
        osal_msleep(RADAR_STATUS_QUERY_DELAY);
        uint8_t sts;
        uapi_radar_get_status(&sts);
        uint16_t time;
        uapi_radar_get_delay_time(&time);
        uint16_t iso;
        uapi_radar_get_isolation(&iso);
        osal_printk("[RADAR_CONTROL] status:%s, time:%u, iso:%u\r\n",
                    sts == RADAR_STATUS_RUNNING ? "working" : "no working", time, iso);
    }
}

void radar_led_on_by_user_flag(uint8_t onoff)
{
    led_on_by_user_flag = onoff;
}

void radar_set_enable_flag(uint8_t onoff)
{
    enable_radar_on_off = onoff;
}

int radar_get_enable_flag(void)
{
    return enable_radar_on_off;
}
// void radar_task_create(void)
// {
//     uint32_t ret;
//     osal_task *taskid;
//     osal_printk("[RADAR_CONTROL] radar_task_create!\r\n");
//     // 创建任务调度
//     osal_kthread_lock();
//     // 创建任务1
//     taskid = osal_kthread_create((osal_kthread_handler)radar_check_status_task, NULL, "radar_check_status_task",
//                                  RADAR_TASK_STACK_SIZE);
//     ret = osal_kthread_set_priority(taskid, RADAR_TASK_PRIO);
//     if (ret != OSAL_SUCCESS) {
//         osal_printk("create radar_check_status_task failed .\n");
//     }
//     osal_kthread_unlock();
// }

void radar_task_create(void)
{
    osThreadAttr_t attr;
    attr.name = "radar_check_status_task";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = RADAR_TASK_STACK_SIZE;
    attr.priority = RADAR_TASK_PRIO;
    osal_printk("[rgb_master]radar_check_status_task start \r\n");
    if (osThreadNew((osThreadFunc_t)radar_check_status_task, NULL, &attr) == NULL) {
        osal_printk("[rgb_master] Failed to create radar_check_status_task!\n");
    }
}
